import { Sprite } from './sprite';

export class Scene {
    private ctx!: CanvasRenderingContext2D;
    private textures = new Map();
    public children: Sprite[] = [];
    public width!: number;
    public height!: number;

    /**
     * 
     * @param dom canvas 父元素
     * @param canvas canvas
     */
    constructor(
        dom: Element,
        canvas: HTMLCanvasElement
    ) {
        this.width = (dom.clientWidth || 0) * 2;
        this.height = (dom.clientHeight || 0) * 2;
        canvas.width = this.width;
        canvas.height = this.height;
        this.ctx = canvas.getContext('2d') as CanvasRenderingContext2D;
    }

    private renderChildSprite(sp: Sprite) {
        const texturesName = sp.texture;
        const texture = this.textures.get(texturesName);
        if (!texture) {
            console.warn(`texture ${texturesName} 不存在`);
            return;
        }
        const canvas = sp.render(texture, [this.width, this.height]);
        this.ctx.drawImage(
            canvas,
            0, 0,
            this.width, this.height
        );
    }

    public load(sources: Record<string, string>) {
        return new Promise(resolve => {
            let count = 0;
            const sourceKeys = Object.keys(sources);
            sourceKeys.forEach(key => {
                const img = new Image();
                img.src = sources[key];
                img.onload = () => {
                    this.textures.set(key, img);
                    count++;
                    if (count === sourceKeys.length) {
                        resolve(true);
                    }
                };
                img.onerror = () => {
                    count++;
                    if (count === sourceKeys.length) {
                        resolve(true);
                    }
                };
            });
        });
    }

    public addChild(sp: Sprite) {
        this.children.push(sp);
        this.renderChildSprite(sp);
    }

    // 清空画板
    public clean() {
        this.ctx.clearRect(0, 0, this.width, this.height);
    }

    // 清空children
    public clearChildren() {
        this.children = [];
    }

    // 通过缓存的chilren数据重新渲染
    public reRenderByCache() {
        this.clean();
        this.children.forEach(item => {
            this.renderChildSprite(item);
        });
    }
}
